package com.tanklab.signature.common.util.sm2Util;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;

import static ch.qos.logback.core.encoder.ByteArrayUtil.hexStringToByteArray;

/**
 * 国密公私钥对工具类
 */
@Slf4j
public class KeyUtils {
    public static final String PUBLIC_KEY = "publicKey";

    public static final String BASE_PUBLIC_KEY = "base_publicKey";

    public static final String PRIVATE_KEY = "privateKey";

    public static final String PRIVATE_KEY_D = "privateKeyD";

    public static final String PUBLIC_KEY_Q = "publicKeyQ";

    /**
     * 生成国密公私钥对
     */
    public static Map<String, String> generateSmKey() throws Exception {
        KeyPairGenerator keyPairGenerator = null;
        SecureRandom secureRandom = new SecureRandom();
        ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
        keyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
        keyPairGenerator.initialize(sm2Spec);
        keyPairGenerator.initialize(sm2Spec, secureRandom);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

//        BCECPublicKey bcpk =(BCECPublicKey)publicKey;
//        String pk = String.format("04%064x",bcpk.getQ().getXCoord().toBigInteger());
//        pk = pk + String.format("%64x",bcpk.getQ().getYCoord().toBigInteger());

        String pk = Hex.toHexString(((BCECPublicKey) publicKey).getQ().getEncoded( false));

//        String sk = String.format("%064x",((BCECPrivateKey)privateKey).getD());

        String publicKeyStr = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
        String privateKeyStr = new String(Base64.getEncoder().encode(privateKey.getEncoded()));
        return Map.of(PUBLIC_KEY, pk, PRIVATE_KEY, privateKeyStr,BASE_PUBLIC_KEY,publicKeyStr);//pk为hex编码,publicKeyStr为base64编码

    }

    /**
     * 将Base64转码的公钥串，转化为公钥对象
     */
    public static PublicKey createPublicKeyFromBase(String publicKey) {
        PublicKey publickey = null;
        try {
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
            KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
            publickey = keyFactory.generatePublic(publicKeySpec);
        } catch (Exception e) {
            log.error("将Base64转码的公钥串，转化为公钥对象异常：{}", e.getMessage(), e);
        }
        return publickey;
    }

    public static PublicKey createPublicKeyFromHex(String hexPublicKey) {
        PublicKey publicKey = null;
        try {
            byte[] decodedKey = hexStringToByteArray(hexPublicKey);
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(decodedKey);
            KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
            publicKey = keyFactory.generatePublic(publicKeySpec);
        } catch (Exception e) {
            log.error("将Hex转码的公钥串，转化为公钥对象异常：{}", e.getMessage(), e);
        }
        return publicKey;
    }

    /**
     * 将Base64转码的私钥串，转化为私钥对象
     */
    public static PrivateKey createPrivateKey(String privateKey) {
        PrivateKey publickey = null;
        try {
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
            KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());
            publickey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            log.error("将Base64转码的私钥串，转化为私钥对象异常：{}", e.getMessage(), e);
        }
        return publickey;
    }

}
